<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ploy4J - 管理服务器配置</title>
    <meta name="_csrf" th:content="${_csrf?.token}"/>
    <meta name="_csrf_header" th:content="${_csrf != null ? _csrf.headerName : ''}"/>
    <link rel="icon" href="/img/favicon.ico" type="image/x-icon">
    <!-- 引入Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- 引入Bootstrap图标 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
    <style>
        .goploy-panel {
            padding: 20px;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .goploy-table th {
            background-color: #f8f9fa;
        }
        .toolbar {
            background-color: #f8f9fa;
            border: 1px solid #dee2e6;
        }
        .btn-group-sm .btn {
            padding: 0.25rem 0.5rem;
        }
        .modal-backdrop {
            z-index: 1040;
        }
        .modal {
            z-index: 1050;
        }
    </style>
</head>
<body>
    <div class="goploy-panel ploy4j-page-content" id="server-management-content">
        <!-- 工具栏 -->
        <div class="toolbar d-flex align-items-center mb-3 p-2 rounded">
            <input type="text" id="serverNameFilter" class="form-control form-control-sm me-2" placeholder="按名称筛选" style="max-width: 180px;">
            <input type="text" id="serverHostFilter" class="form-control form-control-sm me-2" placeholder="按主机筛选" style="max-width: 180px;">
            <div class="ms-auto d-flex align-items-center">
                <button class="btn btn-primary btn-sm d-flex align-items-center" id="newServerBtn">
                    <i class="bi bi-plus-lg me-1"></i> 新建服务器
                </button>
            </div>
        </div>
        
        <!-- 服务器表格 -->
        <div class="table-responsive">
            <table class="table table-hover table-sm caption-top goploy-table">
                <thead class="table-light">
                    <tr>
                        <th style="width: 5%;">ID</th>
                        <th>名称</th>
                        <th>主机IP</th>
                        <th>端口</th>
                        <th>用户名</th>
                        <th class="text-center">创建时间</th>
                        <th class="text-center">更新时间</th>
                        <th class="text-center" style="width: 15%;">操作</th>
                    </tr>
                </thead>
                <tbody id="serverTableBody">
                    <!-- 服务器数据行将通过JavaScript动态插入 -->
                </tbody>
            </table>
        </div>
        
        <!-- 分页控制 -->
        <div id="serverListPagination" class="mt-3 d-flex justify-content-end">
            <!-- 分页内容将通过JavaScript添加 -->
        </div>
        
        <!-- 无数据提示 -->
        <div id="noServersMessage" class="alert alert-info text-center" style="display: none;">
            暂无服务器配置，请点击右上角 "新建服务器" 按钮进行添加。
        </div>

        <!-- 服务器配置模态框 -->
        <div class="modal fade" id="serverConfigModal" tabindex="-1" aria-labelledby="serverConfigModalLabel" aria-hidden="true">
            <div class="modal-dialog modal-lg">
                <div class="modal-content">
                    <form id="serverConfigForm" class="needs-validation" novalidate>
                        <input type="hidden" id="serverId" name="id">
                        <div class="modal-header">
                            <h5 class="modal-title" id="serverConfigModalLabel">新建服务器</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                        </div>
                        <div class="modal-body">
                            <div class="mb-3">
                                <label for="serverName" class="form-label">名称 <span class="text-danger">*</span></label>
                                <input type="text" class="form-control" id="serverName" name="name" required>
                                <div class="invalid-feedback">请输入服务器名称</div>
                            </div>
                            <div class="mb-3">
                                <label for="serverHost" class="form-label">IP <span class="text-danger">*</span></label>
                                <input type="text" class="form-control" id="serverHost" name="host" required>
                                <div class="invalid-feedback">请输入服务器IP地址</div>
                            </div>
                            <div class="mb-3">
                                <label for="serverPort" class="form-label">Port <span class="text-danger">*</span></label>
                                <input type="number" class="form-control" id="serverPort" name="port" value="22" required>
                                <div class="invalid-feedback">请输入有效的端口号</div>
                            </div>
                            <div class="mb-3">
                                <label for="serverUsername" class="form-label">用户名 <span class="text-danger">*</span></label>
                                <input type="text" class="form-control" id="serverUsername" name="username" required>
                                <div class="invalid-feedback">请输入用户名</div>
                            </div>
                            <div class="mb-3">
                                <label for="serverPassword" class="form-label">密码 <span id="passwordRequiredAsterisk" class="text-danger">*</span></label>
                                <div class="input-group">
                                    <input type="password" class="form-control" id="serverPassword" name="password" required>
                                    <button class="btn btn-outline-secondary toggle-password" type="button" title="显示/隐藏密码">
                                        <i class="bi bi-eye"></i>
                                    </button>
                                </div>
                                <small id="passwordHelpBlock" class="form-text text-muted" style="display:none;">
                                    编辑时，若不修改密码则无需填写。
                                </small>
                                <div class="invalid-feedback">请输入密码</div>
                            </div>
                            <div id="testConnectionResultModal" class="mt-3" style="display: none;"></div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-outline-secondary me-auto" id="testConnectionInModalBtn">
                                <i class="bi bi-shield-check me-1"></i> 测试连接
                            </button>
                            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                            <button type="submit" class="btn btn-primary" id="saveServerConfigBtn">保存</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
        
        <!-- 操作结果通知容器 -->
        <div id="notificationsContainer" style="position: fixed; top: 80px; right: 20px; z-index: 1055;"></div>
    </div>

    <!-- 引入Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script>
    // 确保initServerManagement函数在全局作用域中定义
    window.initServerManagement = function() {
        console.log("正在初始化服务器配置管理...");
        
        // 使用立即执行函数封装功能模块
        const ServerManagement = (function() {
            // 私有变量
            let serverTable;
            let serverData = [];
            const csrfToken = document.querySelector('meta[name="_csrf"]')?.getAttribute('content') || '';
            const csrfHeader = document.querySelector('meta[name="_csrf_header"]')?.getAttribute('content') || '';
            
            // DOM元素缓存
            const elements = {
                serverForm: document.getElementById('serverConfigForm'),
                serverModal: null, // 将在initBootstrapModal中设置
                serverTableBody: document.getElementById('serverTableBody'),
                testConnectionBtn: document.getElementById('testConnectionInModalBtn'),
                saveServerBtn: document.getElementById('saveServerConfigBtn'),
                refreshBtn: document.getElementById('refreshServerListBtn'),
                nameFilter: document.getElementById('serverNameFilter'),
                hostFilter: document.getElementById('serverHostFilter'),
                passwordField: document.getElementById('serverPassword'),
                togglePasswordBtn: document.querySelector('.toggle-password')
            };
            
            // 初始化模态框
            function initModal() {
                const serverModal = document.getElementById('serverConfigModal');
                if (!serverModal) {
                    console.error('找不到服务器模态框元素: serverConfigModal');
                    return;
                }
                
                try {
                    const modal = new bootstrap.Modal(serverModal);
                    elements.serverModal = modal;
                    
                    // 监听模态框隐藏事件
                    serverModal.addEventListener('hidden.bs.modal', function() {
                        resetForm();
                        cleanupModalBackdrop();
                    });
                    
                    // 为新建服务器按钮添加事件监听
                    const newServerBtn = document.getElementById('newServerBtn');
                    if (newServerBtn) {
                        newServerBtn.addEventListener('click', function() {
                            resetForm();
                            const modalTitle = document.getElementById('serverConfigModalLabel');
                            if (modalTitle) modalTitle.textContent = '新建服务器';
                            
                            const passwordAsterisk = document.getElementById('passwordRequiredAsterisk');
                            if (passwordAsterisk) passwordAsterisk.style.display = 'inline';
                            
                            const passwordHelp = document.getElementById('passwordHelpBlock');
                            if (passwordHelp) passwordHelp.style.display = 'none';
                            
                            modal.show();
                        });
                    }
                    
                    // 为密码切换按钮添加事件监听
                    if (elements.togglePasswordBtn) {
                        elements.togglePasswordBtn.addEventListener('click', togglePasswordVisibility);
                    }
                    
                    // 为表单添加提交事件监听
                    if (elements.serverForm) {
                        elements.serverForm.addEventListener('submit', saveServerConfig);
                    }
                    
                    // 为测试连接按钮添加事件监听
                    if (elements.testConnectionBtn) {
                        elements.testConnectionBtn.addEventListener('click', testUnsavedConnection);
                    }
                    
                    // 为刷新按钮添加事件监听
                    if (elements.refreshBtn) {
                        elements.refreshBtn.addEventListener('click', loadServerData);
                    }
                    
                    // 为筛选输入框添加事件监听
                    if (elements.nameFilter) {
                        elements.nameFilter.addEventListener('input', filterServers);
                    }
                    if (elements.hostFilter) {
                        elements.hostFilter.addEventListener('input', filterServers);
                    }
                    
                } catch (error) {
                    console.error('初始化模态框失败:', error);
                }
            }
            
            // 清理模态框背景
            function cleanupModalBackdrop() {
                const backdrops = document.querySelectorAll('.modal-backdrop');
                backdrops.forEach(backdrop => backdrop.remove());
                document.body.classList.remove('modal-open');
                document.body.style.removeProperty('overflow');
                document.body.style.removeProperty('padding-right');
            }
            
            // 重置表单
            function resetForm() {
                if (elements.serverForm) {
                    elements.serverForm.reset();
                    elements.serverForm.classList.remove('was-validated');
                    elements.serverForm.elements.id.value = '';
                    
                    const invalidFeedbacks = elements.serverForm.querySelectorAll('.invalid-feedback');
                    invalidFeedbacks.forEach(el => el.style.display = 'none');
                    
                    const formControls = elements.serverForm.querySelectorAll('.form-control');
                    formControls.forEach(el => {
                        el.classList.remove('is-invalid');
                        el.classList.remove('is-valid');
                    });
                }
            }
            
            // 加载服务器数据
            function loadServerData() {
                showLoading(elements.serverTableBody);
                
                fetch('/api/server-configs')
                    .then(response => {
                        if (!response.ok) {
                            throw new Error('服务器数据加载失败: ' + response.status);
                        }
                        return response.json();
                    })
                    .then(data => {
                        serverData = Array.isArray(data) ? data : [];
                        renderServerTable();
                    })
                    .catch(error => {
                        console.error('加载服务器列表出错:', error);
                        showErrorMessage(elements.serverTableBody, '加载服务器列表失败: ' + error.message);
                    });
            }
            
            // 渲染服务器表格
            function renderServerTable() {
                const tableBody = elements.serverTableBody;
                if (!tableBody) {
                    console.error('找不到服务器表格主体元素');
                    return;
                }
                
                tableBody.innerHTML = '';
                
                if (!serverData || serverData.length === 0) {
                    const emptyRow = document.createElement('tr');
                    emptyRow.innerHTML = `
                        <td colspan="8" class="text-center py-3">
                            <div class="alert alert-info mb-0">
                                <i class="bi bi-info-circle me-2"></i>暂无服务器配置数据
                            </div>
                        </td>
                    `;
                    tableBody.appendChild(emptyRow);
                    return;
                }
                
                serverData.forEach((server) => {
                    const row = document.createElement('tr');
                    row.innerHTML = `
                        <td>${server.id || '-'}</td>
                        <td>${escapeHtml(server.name)}</td>
                        <td>${escapeHtml(server.host)}</td>
                        <td>${server.port || 22}</td>
                        <td>${escapeHtml(server.username)}</td>
                        <td class="text-center">${formatDateTime(server.createdAt)}</td>
                        <td class="text-center">${formatDateTime(server.updatedAt)}</td>
                        <td class="text-center">
                            <div class="btn-group btn-group-sm">
                                <button type="button" class="btn btn-outline-info test-conn-btn" data-id="${server.id}" title="测试连接">
                                    <i class="bi bi-shield-check"></i>
                                </button>
                                <button type="button" class="btn btn-outline-primary edit-server-btn" data-id="${server.id}" title="编辑">
                                    <i class="bi bi-pencil-square"></i>
                                </button>
                                <button type="button" class="btn btn-outline-danger delete-server-btn" data-id="${server.id}" title="删除">
                                    <i class="bi bi-trash"></i>
                                </button>
                            </div>
                        </td>
                    `;
                    tableBody.appendChild(row);
                    
                    // 为按钮添加事件监听
                    const testBtn = row.querySelector('.test-conn-btn');
                    if (testBtn) {
                        testBtn.addEventListener('click', () => testServerConnection(server.id, testBtn));
                    }
                    
                    const editBtn = row.querySelector('.edit-server-btn');
                    if (editBtn) {
                        editBtn.addEventListener('click', () => editServer(server.id));
                    }
                    
                    const deleteBtn = row.querySelector('.delete-server-btn');
                    if (deleteBtn) {
                        deleteBtn.addEventListener('click', () => confirmDeleteServer(server.id, server.name));
                    }
                });
            }
            
            // 编辑服务器
            function editServer(id) {
                const server = serverData.find(s => s.id === id);
                if (!server) {
                    console.error('未找到ID为 ' + id + ' 的服务器数据');
                    return;
                }
                
                // 填充表单
                const form = elements.serverForm;
                if (form) {
                    form.elements.id.value = server.id;
                    form.elements.name.value = server.name || '';
                    form.elements.host.value = server.host || '';
                    form.elements.port.value = server.port || 22;
                    form.elements.username.value = server.username || '';
                    form.elements.password.value = ''; // 出于安全考虑，不回填密码
                    
                    // 更新模态框标题
                    const modalTitle = document.getElementById('serverConfigModalLabel');
                    if (modalTitle) modalTitle.textContent = '编辑服务器配置';
                    
                    // 显示密码提示
                    const passwordAsterisk = document.getElementById('passwordRequiredAsterisk');
                    if (passwordAsterisk) passwordAsterisk.style.display = 'none';
                    
                    const passwordHelp = document.getElementById('passwordHelpBlock');
                    if (passwordHelp) passwordHelp.style.display = 'block';
                    
                    // 显示模态框
                    elements.serverModal.show();
                }
            }
            
            // 确认删除服务器
            function confirmDeleteServer(id, name) {
                if (confirm(`确认要删除服务器 "${name}" 吗？`)) {
                    deleteServer(id);
                }
            }
            
            // 删除服务器
            function deleteServer(id) {
                const headers = {
                    'Content-Type': 'application/json'
                };
                
                if (csrfToken && csrfHeader) {
                    headers[csrfHeader] = csrfToken;
                }
                
                fetch(`/api/server-configs/${id}`, {
                    method: 'DELETE',
                    headers: headers
                })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('删除失败: ' + response.status);
                    }
                    return response.json();
                })
                .then(data => {
                    if (data.success) {
                        showSuccessToast('服务器配置删除成功');
                        loadServerData(); // 重新加载数据
                    } else {
                        showErrorToast('删除失败: ' + (data.message || '未知错误'));
                    }
                })
                .catch(error => {
                    console.error('删除服务器配置出错:', error);
                    showErrorToast('删除失败: ' + error.message);
                });
            }
            
            // 测试服务器连接
            function testServerConnection(id, testBtn) {
                const server = serverData.find(s => s.id === id);
                if (!server) {
                    console.error('未找到ID为 ' + id + ' 的服务器数据');
                    showErrorToast('无法测试：未找到服务器数据');
                    return;
                }
                
                const headers = {
                    'Content-Type': 'application/json'
                };
                
                if (csrfToken && csrfHeader) {
                    headers[csrfHeader] = csrfToken;
                }
                
                // 禁用测试按钮
                if (testBtn) {
                    testBtn.disabled = true;
                    testBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 测试中...';
                }
                
                // 发送测试请求
                fetch(`/api/server-configs/${id}/test-connection`, {
                    method: 'POST',
                    headers: headers
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        showSuccessToast('连接测试成功！');
                    } else {
                        showErrorToast('连接测试失败: ' + (data.message || '未知错误'));
                    }
                })
                .catch(error => {
                    console.error('连接测试出错:', error);
                    showErrorToast('连接测试错误: ' + error.message);
                })
                .finally(() => {
                    // 恢复测试按钮
                    if (testBtn) {
                        testBtn.disabled = false;
                        testBtn.innerHTML = '<i class="bi bi-shield-check"></i>';
                    }
                });
            }
            
            // 测试未保存的连接
            function testUnsavedConnection() {
                const form = elements.serverForm;
                if (!form) return;
                
                // 表单验证
                if (!form.checkValidity()) {
                    form.classList.add('was-validated');
                    return;
                }
                
                // 构建测试数据
                const testData = {
                    host: form.elements.host.value,
                    port: parseInt(form.elements.port.value) || 22,
                    username: form.elements.username.value,
                    password: form.elements.password.value || null
                };
                
                const headers = {
                    'Content-Type': 'application/json'
                };
                
                if (csrfToken && csrfHeader) {
                    headers[csrfHeader] = csrfToken;
                }
                
                // 禁用测试按钮
                const testBtn = elements.testConnectionBtn;
                if (testBtn) {
                    testBtn.disabled = true;
                    testBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 测试中...';
                }
                
                // 发送测试请求
                fetch('/api/server-configs/test-unsaved-connection', {
                    method: 'POST',
                    headers: headers,
                    body: JSON.stringify(testData)
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        showSuccessToast('连接测试成功！');
                    } else {
                        showErrorToast('连接测试失败: ' + (data.message || '未知错误'));
                    }
                })
                .catch(error => {
                    console.error('连接测试出错:', error);
                    showErrorToast('连接测试错误: ' + error.message);
                })
                .finally(() => {
                    // 恢复测试按钮
                    if (testBtn) {
                        testBtn.disabled = false;
                        testBtn.innerHTML = '<i class="bi bi-shield-check me-1"></i> 测试连接';
                    }
                });
            }
            
            // 保存服务器配置
            function saveServerConfig(event) {
                event.preventDefault();
                
                const form = elements.serverForm;
                if (!form) return;
                
                // 表单验证
                if (!form.checkValidity()) {
                    form.classList.add('was-validated');
                    return;
                }
                
                // 构建表单数据
                const formData = {
                    id: form.elements.id.value || null,
                    name: form.elements.name.value,
                    host: form.elements.host.value,
                    port: parseInt(form.elements.port.value) || 22,
                    username: form.elements.username.value,
                    password: form.elements.password.value || null
                };
                
                const headers = {
                    'Content-Type': 'application/json'
                };
                
                if (csrfToken && csrfHeader) {
                    headers[csrfHeader] = csrfToken;
                }
                
                // 禁用保存按钮
                const saveBtn = elements.saveServerBtn;
                if (saveBtn) {
                    saveBtn.disabled = true;
                    saveBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 保存中...';
                }
                
                // 决定请求方法
                const method = formData.id ? 'PUT' : 'POST';
                const url = formData.id ? `/api/server-configs/${formData.id}` : '/api/server-configs';
                
                // 发送请求
                fetch(url, {
                    method: method,
                    headers: headers,
                    body: JSON.stringify(formData)
                })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('保存失败: ' + response.status);
                    }
                    return response.json();
                })
                .then(data => {
                    // 显示成功提示
                    showSuccessToast('服务器配置保存成功');
                    
                    // 关闭模态框并清理背景
                    elements.serverModal.hide();
                    cleanupModalBackdrop();
                    
                    // 重新加载数据
                    loadServerData();
                })
                .catch(error => {
                    console.error('保存服务器配置出错:', error);
                    showErrorToast('保存失败: ' + error.message);
                })
                .finally(() => {
                    // 恢复保存按钮
                    if (saveBtn) {
                        saveBtn.disabled = false;
                        saveBtn.innerHTML = '保存';
                    }
                });
            }
            
            // 切换密码可见性
            function togglePasswordVisibility() {
                const passwordField = elements.passwordField;
                const toggleBtn = elements.togglePasswordBtn;
                
                if (passwordField && toggleBtn) {
                    if (passwordField.type === 'password') {
                        passwordField.type = 'text';
                        toggleBtn.innerHTML = '<i class="bi bi-eye-slash"></i>';
                    } else {
                        passwordField.type = 'password';
                        toggleBtn.innerHTML = '<i class="bi bi-eye"></i>';
                    }
                }
            }
            
            // 筛选服务器
            function filterServers() {
                const nameFilter = elements.nameFilter.value.toLowerCase();
                const hostFilter = elements.hostFilter.value.toLowerCase();
                
                const filteredData = serverData.filter(server => {
                    const nameMatch = server.name.toLowerCase().includes(nameFilter);
                    const hostMatch = server.host.toLowerCase().includes(hostFilter);
                    return nameMatch && hostMatch;
                });
                
                renderFilteredTable(filteredData);
            }
            
            // 渲染筛选后的表格
            function renderFilteredTable(filteredData) {
                const tableBody = elements.serverTableBody;
                if (!tableBody) return;
                
                tableBody.innerHTML = '';
                
                if (!filteredData || filteredData.length === 0) {
                    const emptyRow = document.createElement('tr');
                    emptyRow.innerHTML = `
                        <td colspan="8" class="text-center py-3">
                            <div class="alert alert-info mb-0">
                                <i class="bi bi-info-circle me-2"></i>没有找到匹配的服务器配置
                            </div>
                        </td>
                    `;
                    tableBody.appendChild(emptyRow);
                    return;
                }
                
                filteredData.forEach((server) => {
                    const row = document.createElement('tr');
                    row.innerHTML = `
                        <td>${server.id || '-'}</td>
                        <td>${escapeHtml(server.name)}</td>
                        <td>${escapeHtml(server.host)}</td>
                        <td>${server.port || 22}</td>
                        <td>${escapeHtml(server.username)}</td>
                        <td class="text-center">${formatDateTime(server.createdAt)}</td>
                        <td class="text-center">${formatDateTime(server.updatedAt)}</td>
                        <td class="text-center">
                            <div class="btn-group btn-group-sm">
                                <button type="button" class="btn btn-outline-info test-conn-btn" data-id="${server.id}" title="测试连接">
                                    <i class="bi bi-shield-check"></i>
                                </button>
                                <button type="button" class="btn btn-outline-primary edit-server-btn" data-id="${server.id}" title="编辑">
                                    <i class="bi bi-pencil-square"></i>
                                </button>
                                <button type="button" class="btn btn-outline-danger delete-server-btn" data-id="${server.id}" title="删除">
                                    <i class="bi bi-trash"></i>
                                </button>
                            </div>
                        </td>
                    `;
                    tableBody.appendChild(row);
                    
                    // 为按钮添加事件监听
                    const testBtn = row.querySelector('.test-conn-btn');
                    if (testBtn) {
                        testBtn.addEventListener('click', () => testServerConnection(server.id, testBtn));
                    }
                    
                    const editBtn = row.querySelector('.edit-server-btn');
                    if (editBtn) {
                        editBtn.addEventListener('click', () => editServer(server.id));
                    }
                    
                    const deleteBtn = row.querySelector('.delete-server-btn');
                    if (deleteBtn) {
                        deleteBtn.addEventListener('click', () => confirmDeleteServer(server.id, server.name));
                    }
                });
            }
            
            // 辅助函数: 显示加载状态
            function showLoading(container) {
                if (container) {
                    container.innerHTML = `
                        <tr>
                            <td colspan="8" class="text-center py-4">
                                <div class="d-flex justify-content-center">
                                    <div class="spinner-border text-primary" role="status">
                                        <span class="visually-hidden">加载中...</span>
                                    </div>
                                </div>
                                <div class="mt-2">正在加载服务器配置...</div>
                            </td>
                        </tr>
                    `;
                }
            }
            
            // 辅助函数: 显示错误消息
            function showErrorMessage(container, message) {
                if (container) {
                    container.innerHTML = `
                        <tr>
                            <td colspan="8" class="text-center py-3">
                                <div class="alert alert-danger mb-0">
                                    <i class="bi bi-exclamation-triangle me-2"></i>${escapeHtml(message)}
                                </div>
                            </td>
                        </tr>
                    `;
                }
            }
            
            // 辅助函数: 显示成功提示
            function showSuccessToast(message) {
                const container = document.getElementById('notificationsContainer');
                if (!container) return;
                
                const toast = document.createElement('div');
                toast.className = 'toast show bg-success text-white';
                toast.setAttribute('role', 'alert');
                toast.setAttribute('aria-live', 'assertive');
                toast.setAttribute('aria-atomic', 'true');
                
                toast.innerHTML = `
                    <div class="toast-body">
                        <i class="bi bi-check-circle me-2"></i>${escapeHtml(message)}
                    </div>
                `;
                
                container.appendChild(toast);
                
                // 3秒后自动移除
                setTimeout(() => {
                    toast.remove();
                }, 3000);
            }
            
            // 辅助函数: 显示错误提示
            function showErrorToast(message) {
                const container = document.getElementById('notificationsContainer');
                if (!container) return;
                
                const toast = document.createElement('div');
                toast.className = 'toast show bg-danger text-white';
                toast.setAttribute('role', 'alert');
                toast.setAttribute('aria-live', 'assertive');
                toast.setAttribute('aria-atomic', 'true');
                
                toast.innerHTML = `
                    <div class="toast-body">
                        <i class="bi bi-exclamation-triangle me-2"></i>${escapeHtml(message)}
                    </div>
                `;
                
                container.appendChild(toast);
                
                // 3秒后自动移除
                setTimeout(() => {
                    toast.remove();
                }, 3000);
            }
            
            // 辅助函数: 转义HTML
            function escapeHtml(unsafe) {
                return unsafe
                    .replace(/&/g, "&amp;")
                    .replace(/</g, "&lt;")
                    .replace(/>/g, "&gt;")
                    .replace(/"/g, "&quot;")
                    .replace(/'/g, "&#039;");
            }
            
            // 辅助函数: 格式化日期时间
            function formatDateTime(dateTimeStr) {
                if (!dateTimeStr) return '-';
                const date = new Date(dateTimeStr);
                return date.toLocaleString('zh-CN', {
                    year: 'numeric',
                    month: '2-digit',
                    day: '2-digit',
                    hour: '2-digit',
                    minute: '2-digit',
                    second: '2-digit'
                });
            }
            
            // 初始化
            function init() {
                initModal();
                loadServerData();
            }
            
            // 返回公共方法
            return {
                init: init
            };
        })();
        
        // 初始化服务器管理
        ServerManagement.init();
    };
    
    // 页面加载完成后初始化
    document.addEventListener('DOMContentLoaded', function() {
        if (typeof initServerManagement === 'function') {
            initServerManagement();
        } else {
            console.error('initServerManagement 函数未定义');
        }
    });
    </script>
</body>
</html> 